//声明Promise并绑定this
class MyPromise{
    //等待
    static PENDING = 'pending';
    //成功
    static FULFILLED = 'fulfilled';
    //失败
    static REJECTED = 'rejected';

    constructor(excutor){
        this.status = MyPromise.PENDING;
        this.value = null;
        this.callbacks = [];
        //异常捕获，并调用reject做失败处理
        try{ 
            excutor(this.resolve.bind(this), this.reject.bind(this))
            // excutor(this.resolve, this.reject) //Cannot set property 'status' of undefined
        }catch(error){
            this.reject(error)
        }
    }

    resolve(value){
        // console.log('value:'+value+', type:'+(typeof value))
        //状态保护，成功或者失败后不能更改状态
        if(this.status !== MyPromise.PENDING) return
        this.status = MyPromise.FULFILLED;
        this.value = value;
        setTimeout(() => {
            this.callbacks.map(callback => {
                callback.onFulfilled(this.value)
            })
        },0)
    }

    reject(reason){
        //状态保护，成功或者失败后不能更改状态
        if(this.status !== MyPromise.PENDING) return 
        this.status = MyPromise.REJECTED;
        this.value = reason;
        setTimeout(() => {
            this.callbacks.map(callback => {
                callback.onRejected(this.value)
            })
        },0)
    }

    then(onFulfilled, onRejected){
        if(typeof onFulfilled !== 'function'){//如果成功回调不写，声明一个方法，避免报错
            onFulfilled = () => this.value;
        }
        if(typeof onRejected !== 'function'){//如果失败回调不写，声明一个方法，避免报错
            onRejected = () => this.value;
        }
        //解决链式调用，返回一个promise
        let promise = new MyPromise((resolve, reject) => {
            //状态为成功的时候才执行then里面的成功回调
            if(this.status == MyPromise.FULFILLED){
                setTimeout(() => {
                    resolvePromise(promise, onFulfilled(this.value), resolve, reject);
                }, 0)
            } else if(this.status == MyPromise.REJECTED){//加上条件判断，状态为成功的时候才执行then里面的失败回调
                setTimeout(() => {
                    resolvePromise(promise, onRejected(this.value), resolve, reject);
                    
                }, 0)
            } else{//this.status == MyPromise.PENDING
                this.callbacks.push({
                    onFulfilled: value => {
                        resolvePromise(promise, onFulfilled(value), resolve, reject);
                    },
                    onRejected: value => {
                        resolvePromise(promise, onRejected(value), resolve, reject);
                    }
                })
            }
        })
        return promise;
    }
    static resolve(value){
        return new MyPromise((resolve,reject) => {
            if(value instanceof MyPromise){
                value.then(resolve, reject);
            }else{
                resolve(value);
            }
        })
    }
    static reject(value){
        return new MyPromise((resolve,reject) => {
            reject(value)
        })
    }
    static all(promises){
        //计数，如果都执行成功则调用resolve方法
        const values = [];
        return new MyPromise((resolve,reject) => {
            promises.forEach((promise) => {
                promise.then(value => {
                    values.push(value);
                    if(values.length == promise.length){
                        resolve(values)
                    }
                }, reason => {
                    reject(reason);
                })
            })
        })
    }
}

//判断执行结果是普通值还是Promise对象
function resolvePromise(promise, result, resolve, reject){
    if(promise == result){
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    try{
        //如果是promise对象，则返回peomise对象的返回结果
        if(result instanceof MyPromise){
            result.then(resolve, reject)
        }else{//如果是普通值，调用resolve方法
            resolve(result)
        }
    }catch(error){
        reject('error:'+error);
    }
    
}
// module.exports = MyPromise;